home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Panel Editor / Source / Selection.cpp < prev    next >
Encoding:
Text File  |  1995-12-08  |  19.6 KB  |  748 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Selection.pp
  3.  
  4.     Contains:    Selection class implementation
  5.  
  6.     Written by:    Steve Smith
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- OpenDoc Utilities --
  18.  
  19. #ifndef _EXCEPT_
  20. // Exceptions define several important macros (ie. CHECKENV)
  21. // which are used in the SOM method dispatch glue. If Except.h
  22. // is not included early enough, exceptions may not be thrown
  23. // correctly when returning from a SOM method with the "ev" parameter set.
  24. #include <Except.h>
  25. #endif
  26.  
  27. // -- PanelEditor Includes --
  28.  
  29. #ifndef _SELECTION_
  30. #include "Selection.h"
  31. #endif
  32.  
  33. #ifndef _PANELEDITOR_
  34. #include "PanelEditor.h"
  35. #endif
  36.  
  37. #ifndef _PANELEDITORDEF_
  38. #include "PanelEditorDef.h"
  39. #endif
  40.  
  41. #ifndef _PANELEDITORGLOBALS_
  42. #include "PanelEditorGlobals.h"
  43. #endif
  44.  
  45. #ifndef _LISTITEM_
  46. #include "ListItem.h"
  47. #endif
  48.  
  49. #ifndef _UNDOPE_
  50. #include "UndoPE.h"
  51. #endif
  52.  
  53. #ifndef _SAMPLECOLLECTIONS_
  54. #include "SampleCollections.h"
  55. #endif
  56.  
  57. // -- OpenDoc Includes --
  58.  
  59. #ifndef _ODTYPES_
  60. #include <ODTypes.h>
  61. #endif
  62.  
  63. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  64. #include <StdDefs.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODArbitrator_xh
  68. #include <Arbitrat.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODClipboard_xh
  72. #include <Clipbd.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODUndo_xh
  76. #include <Undo.xh>
  77. #endif
  78.  
  79. #ifndef SOM_ODStorageUnit_xh
  80. #include <StorageU.xh>
  81. #endif
  82.  
  83. #ifndef SOM_ODDragAndDrop_xh
  84. #include <DragDrp.xh>
  85. #endif
  86.  
  87. #ifndef SOM_ODShape_xh
  88. #include <Shape.xh>
  89. #endif
  90.  
  91. // -- OpenDoc Utilities --
  92.  
  93. #ifndef _BARRAY_
  94. #include <BArray.h>
  95. #endif
  96.  
  97. #ifndef _ODUTILS_
  98. #include <ODUtils.h>
  99. #endif
  100.  
  101. #ifndef _STORUTIL_
  102. #include <StorUtil.h>
  103. #endif
  104.  
  105. #ifndef _USERSRCM_
  106. #include <UseRsrcM.h>
  107. #endif
  108.  
  109. #ifndef _ODDEBUG_
  110. #include <ODDebug.h>
  111. #endif
  112.  
  113. #ifndef _ODNEW_
  114. #include <ODNew.h>
  115. #endif
  116.  
  117. #ifndef _FOCUSLIB_
  118. #include <FocusLib.h>
  119. #endif
  120.  
  121. #ifndef _TEMPOBJ_
  122. #include <TempObj.h>
  123. #endif
  124.  
  125. // -- Macintosh Includes --
  126.  
  127. #ifndef __DRAG__
  128. #include <Drag.h>
  129. #endif
  130.  
  131.  
  132. #pragma segment PanelEditorSelection
  133.  
  134. //------------------------------------------------------------------------------
  135. // Method:        Constructor
  136. //------------------------------------------------------------------------------
  137.  
  138. CSelection::CSelection(PanelEditor* owner, ODSession* session)
  139. {
  140.     fItems = kODNULL;
  141.     fOwner = owner;
  142.     fSession = session;
  143.     fInited = kODFalse;
  144. }
  145.  
  146. //------------------------------------------------------------------------------
  147. // Method:        Destructor
  148. //------------------------------------------------------------------------------
  149.  
  150. CSelection::~CSelection()
  151. {
  152.     ASSERT(fInited != kODFalse, kAssertionFailed);
  153.  
  154.     Environment* ev = somGetGlobalEnvironment();
  155.     
  156.     // Remove any remaining items from the selection list.
  157.     this->Empty(ev);
  158. }
  159.         
  160. //------------------------------------------------------------------------------
  161. // Method:        InitSelection
  162. //------------------------------------------------------------------------------
  163.  
  164. void CSelection::InitSelection()
  165. {
  166.     fItems = new CList;
  167.     fInited = kODTrue;
  168. }
  169.  
  170. //------------------------------------------------------------------------------
  171. // Method:        Add
  172. // Description:    Add an item to the selection and set its selected state.
  173. //------------------------------------------------------------------------------
  174.  
  175. void CSelection::Add(Environment* ev, CListItem* item)
  176. {
  177.     ASSERT(fInited != kODFalse, kAssertionFailed);
  178.     ASSERT(fItems != kODNULL, kAssertionFailed);
  179.     
  180.     // Select the item.
  181.     item->SetSelected(ev, kODTrue);
  182.     // Add the item from the selection list.
  183.     fItems->Add((ODPtr)item);
  184.     // Release the selection's reference to the item.
  185.     item->Acquire();
  186. }
  187.  
  188. //------------------------------------------------------------------------------
  189. // Method:        Remove
  190. // Description:    This method is called during
  191. //------------------------------------------------------------------------------
  192.  
  193. void CSelection::Remove(Environment* ev, CListItem* item)
  194. {
  195.     ASSERT(fInited != kODFalse, kAssertionFailed);
  196.     ASSERT(fItems != kODNULL, kAssertionFailed);
  197.     
  198.     // Unselect the item.
  199.     item->SetSelected(ev, kODFalse);
  200.     // Remove the item from the selection list.
  201.     fItems->Remove((ODPtr)item);
  202.     // Release the selection's reference to the item.
  203.     item->Release(ev);
  204. }
  205.  
  206. //------------------------------------------------------------------------------
  207. // Method:        Empty
  208. //
  209. // Description:    This method is called to empty the current selection. The update
  210. //                parameter specifies whether the facet's of the items should have
  211. //                their selected states udpated. There's no need to do this if the
  212. //                item is going away.
  213. //------------------------------------------------------------------------------
  214.  
  215. void CSelection::Empty(Environment* ev, ODBoolean update)
  216. {
  217.     ASSERT(fInited != kODFalse, kAssertionFailed);
  218.     ASSERT(fItems != kODNULL, kAssertionFailed);
  219.     
  220.     // Iterate over the list of items in the selection
  221.     // and remove them.
  222.     CListIterator fiter(fItems);
  223.     for ( CListItem* item = (CListItem*)fiter.First();
  224.             fiter.IsNotComplete();
  225.             item = (CListItem*)fiter.Next() )
  226.     {
  227.         fiter.RemoveCurrent();
  228.         if ( update )
  229.             item->SetSelected(ev, kODFalse);
  230.         item->Release(ev);
  231.     }
  232. }
  233.  
  234. //------------------------------------------------------------------------------
  235. // Method:        IsEmpty
  236. //
  237. // Description:    This method is called during
  238. //------------------------------------------------------------------------------
  239.  
  240. ODBoolean CSelection::IsEmpty()
  241. {
  242.     ASSERT(fInited != kODFalse, kAssertionFailed);
  243.     ASSERT(fItems != kODNULL, kAssertionFailed);
  244.     
  245.     return ( fItems->Count() == 0 );
  246. }
  247.  
  248. //------------------------------------------------------------------------------
  249. // Method:        ClearItems
  250. //
  251. // Description: Remove the items in the selection from the part's list by
  252. //                iterating over the selection and asking the part to remove the
  253. //                items one-at-a-time.
  254. //------------------------------------------------------------------------------
  255.  
  256. void CSelection::ClearItems(Environment* ev)
  257. {
  258.     ASSERT(fInited != kODFalse, kAssertionFailed);
  259.     ASSERT(fItems != kODNULL, kAssertionFailed);
  260.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  261.     
  262.     // We can't remove the items from the list we are iterating over. So we have
  263.     // to make a copy of the current list and iterate over that.
  264.     
  265.     // Copy the list.
  266.     CList* list = new CList;
  267.     CListIterator fiter(fItems);
  268.     for ( CListItem* item = (CListItem*)fiter.First();
  269.             fiter.IsNotComplete();
  270.             item = (CListItem*)fiter.Next() )
  271.     {
  272.         list->Add((ODPtr)item);
  273.     }
  274.     
  275.     // Iterate over the copy, removing each item.
  276.     CListIterator liter(list);
  277.     for ( CListItem* anitem = (CListItem*)liter.First();
  278.             liter.IsNotComplete();
  279.             anitem = (CListItem*)liter.Next() )
  280.     {
  281.         // Ask the owner to remove the item from internal collections.
  282.         fOwner->RemoveListItem(ev, anitem);
  283.         // Detach the item from the document frame hierarchy.
  284.         anitem->Detach(ev);
  285.         // Remove the item from the selection.
  286.         this->Remove(ev, anitem);
  287.     }
  288.     delete list;
  289. }
  290.  
  291. //------------------------------------------------------------------------------
  292. // Method:        CaptureItems
  293. //
  294. // Description:    Duplicate the current selection for Undo.
  295. //------------------------------------------------------------------------------
  296.  
  297. CList* CSelection::CaptureItems()
  298. {
  299.     ASSERT(fInited != kODFalse, kAssertionFailed);
  300.     ASSERT(fItems != kODNULL, kAssertionFailed);
  301.     
  302.     // Clone the selection list to be used for Undo/Redo.
  303.     
  304.     CList* list = new CList;
  305.     
  306.     CListIterator fiter(fItems);
  307.     for ( CListItem* item = (CListItem*)fiter.First();
  308.             fiter.IsNotComplete();
  309.             item = (CListItem*)fiter.Next() )
  310.     {
  311.         list->Add((ODPtr)item);
  312.         item->Acquire();
  313.     }
  314.     
  315.     return list;
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319. // Method:        Activate
  320. //
  321. // Description:    Notify the items in the selection that an activate/deactivate or
  322. //                suspend/resume event is being processed. This is necessary to
  323. //                ensure the items are displayed correctly.
  324. //------------------------------------------------------------------------------
  325.  
  326. void CSelection::Activate(Environment* ev, ODFrame* frame, ODBoolean activate)
  327. {
  328.     ASSERT(fInited != kODFalse, kAssertionFailed);
  329.  
  330.     TempODWindow window = frame->AcquireWindow(ev);
  331.     if ( window )
  332.     {
  333.         ODID windowID = window->GetID(ev);
  334.         
  335.         CListIterator fiter(fItems);
  336.         for ( CListItem* item = (CListItem*)fiter.First();
  337.                 fiter.IsNotComplete();
  338.                 item = (CListItem*)fiter.Next() )
  339.         {
  340.             // The items only care about "suspend" events.
  341.             item->ActivationChanged(ev, windowID, activate);
  342.         }
  343.     }
  344. }
  345.  
  346. //------------------------------------------------------------------------------
  347. // Method:        Write
  348. //
  349. // Description:    Write the items in the selection to the storageUnit passed in.
  350. //------------------------------------------------------------------------------
  351.  
  352. void CSelection::Write(Environment* ev, ODStorageUnit* storageUnit)
  353. {
  354.     ASSERT(fInited != kODFalse, kAssertionFailed);
  355.     ASSERT(fItems != kODNULL, kAssertionFailed);
  356.     
  357.     ODDraft*    fromDraft = ODGetDraft(ev, fOwner->GetSelf());
  358.     ODDraft*    toDraft = ODGetDraft(ev, storageUnit);
  359.     ODDraftKey    draftKey;
  360.     
  361.     ODVolatile(fromDraft);
  362.     ODVolatile(draftKey);
  363.     
  364.     draftKey = fromDraft->BeginClone(ev, toDraft, kODNULLID, kODCloneCopy);
  365.  
  366.     TRY
  367.         // Clone the part in the selection to the storageUnit.
  368.         CListIterator fiter(fItems);
  369.         CListItem* item = (CListItem*)fiter.First();
  370.  
  371.         item->ClonePart(ev, storageUnit, draftKey);
  372.  
  373.         fromDraft->EndClone(ev, draftKey);
  374.     CATCH_ALL
  375.         fromDraft->AbortClone(ev, draftKey);
  376.         // consume exceptions.
  377.     ENDTRY
  378. }
  379.  
  380. //------------------------------------------------------------------------------
  381. // Method:        Cut
  382. //
  383. // Description:    Handle the Edit menu command to cut the selected items.
  384. //------------------------------------------------------------------------------
  385.  
  386. void CSelection::Cut(Environment* ev, ODFrame* frame)
  387. {
  388.     ASSERT(fInited != kODFalse, kAssertionFailed);
  389.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  390.     
  391.     // Call the "copy" method to do the work.
  392.     this->Copy(ev, frame);
  393.  
  394.     // Allow the user to undo/redo the clipboard operation.
  395.     this->PushUndoState(ev, kUndoCut, kODSingleAction);        
  396.  
  397.     // Clear the items in the selection.
  398.     this->ClearItems(ev);
  399. }
  400.  
  401. //------------------------------------------------------------------------------
  402. // Method:        Copy
  403. //
  404. // Description:    Handle the Edit menu command to copy the selected items.
  405. //------------------------------------------------------------------------------
  406.  
  407. void CSelection::Copy(Environment* ev, ODFrame* frame)
  408. {
  409.     ASSERT(fInited != kODFalse, kAssertionFailed);
  410.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  411.     
  412.     ODArbitrator* arbitrator = fSession->GetArbitrator(ev);
  413.     ODClipboard* clipboard = fSession->GetClipboard(ev);
  414.  
  415.     // Acquire the clipboard focus.
  416.     if ( arbitrator->RequestFocus(ev, gGlobals->fClipboardFocus, frame) )
  417.     {
  418.         // Clear out the old junk.
  419.         clipboard->Clear(ev);
  420.         ODStorageUnit* su = clipboard->GetContentStorageUnit(ev);    
  421.  
  422.         // Write out the current selection.
  423.         this->Write(ev, su);
  424.     
  425.         // Relinquish the clipboard focus.
  426.         arbitrator->RelinquishFocus(ev, gGlobals->fClipboardFocus, frame);
  427.     }
  428. }
  429.  
  430. //------------------------------------------------------------------------------
  431. // Method:        Clear
  432. //
  433. // Description:    Handle the Edit menu command to clear the selected items.
  434. //------------------------------------------------------------------------------
  435.  
  436. void CSelection::Clear(Environment* ev, ODFrame* frame)
  437. {
  438.     ASSERT(fInited != kODFalse, kAssertionFailed);
  439.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  440.     
  441.     // Allow the user to undo/redo the clipboard operation.
  442.     this->PushUndoState(ev, kUndoClear, kODSingleAction);        
  443.  
  444.     // Clear the items in the selection.
  445.     this->ClearItems(ev);
  446. }
  447.  
  448. //------------------------------------------------------------------------------
  449. // Method:        ShowPartInfo
  450. //
  451. // Description:    This method is called to display the Part Info dialog for each
  452. //                item in the selection.
  453. //------------------------------------------------------------------------------
  454.  
  455. void CSelection::ShowPartInfo(Environment* ev, ODFrame* frame)
  456. {
  457.     ASSERT(fInited != kODFalse, kAssertionFailed);
  458.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  459.  
  460.     // Iterate over the selection.
  461.     CListIterator fiter(fItems);
  462.     for ( CListItem* item = (CListItem*)fiter.First();
  463.             fiter.IsNotComplete();
  464.             item = (CListItem*)fiter.Next() )
  465.     {
  466.         // Ask each item to display part info for itself.
  467.         item->DoPartInfo(ev, frame);
  468.     }
  469. }
  470.  
  471. //------------------------------------------------------------------------------
  472. // Method:        Undo
  473. //
  474. // Description:    This method is called to undo a previous action.
  475. //------------------------------------------------------------------------------
  476.  
  477. void CSelection::Undo(Environment* ev, CUndo* action)
  478. {
  479.     ASSERT(fInited != kODFalse, kAssertionFailed);
  480.  
  481.     switch ( action->GetType() ) {
  482.         case kUndoCut:
  483.         case kUndoPaste:
  484.         case kUndoClear:
  485.         case kUndoDrop:
  486.         
  487.         default:;
  488.     }
  489. }
  490.  
  491. //------------------------------------------------------------------------------
  492. // Method:        Redo
  493. //
  494. // Description: This method is called to redo a previously undone action.
  495. //------------------------------------------------------------------------------
  496.  
  497. void CSelection::Redo(Environment* ev, CUndo* action)
  498. {
  499.     ASSERT(fInited != kODFalse, kAssertionFailed);
  500.  
  501.     switch ( action->GetType() ) {
  502.         case kUndoCut:
  503.         case kUndoPaste:
  504.         case kUndoClear:
  505.         case kUndoDrop:
  506.         
  507.         default:;
  508.     }
  509. }
  510.  
  511. //------------------------------------------------------------------------------
  512. // Method:        PushUndoState
  513. //
  514. // Description:    This method is called to capture and push the current state of
  515. //                of the selection so that it may later be un/redone.
  516. //------------------------------------------------------------------------------
  517.  
  518. void CSelection::PushUndoState(Environment* ev, ODUShort undoType, ODActionType actionType)
  519. {
  520.     ASSERT(fInited != kODFalse, kAssertionFailed);
  521.     ASSERT(fOwner != kODNULL, kAssertionFailed);
  522.     ASSERT(fSession != kODNULL, kAssertionFailed);
  523.     
  524.     ODIText* undoString = kODNULL;
  525.     ODIText* redoString = kODNULL;
  526.  
  527.     // Store the state to be undone/redone.
  528.     CUndo* undoData = new CUndo;
  529.         
  530.     undoData->SetType(undoType);
  531.     undoData->SetSelection(this->CaptureItems());
  532.     
  533.     // Create an byte array to store the undo information.
  534.     ODActionData action;
  535.     action._length = sizeof(CUndo*);
  536.     action._maximum = sizeof(CUndo*);
  537.     action._buffer = (octet*) &undoData;
  538.     
  539.     ODUndo* undo = fSession->GetUndo(ev);
  540.  
  541.     Str255    text;
  542.     // Get the undo string
  543.     ODGetIndString(text, kUndoStringResID, undoType);
  544.     undoString = CreateIText(gGlobals->fEditorsScript, gGlobals->fEditorsLanguage, (StringPtr)&text);
  545.     
  546.     // Get the redo string
  547.     ODGetIndString(text, kUndoStringResID, undoType+1);
  548.     redoString = CreateIText(gGlobals->fEditorsScript, gGlobals->fEditorsLanguage, (StringPtr)&text);
  549.     
  550.     // Push all the information onto the OpenDoc undo stack.
  551.     TRY
  552.         undo->AddActionToHistory(ev, fOwner->GetSelf(), &action, actionType, undoString, redoString);
  553.     CATCH_ALL
  554.         DisposeIText(undoString);
  555.         DisposeIText(redoString);
  556.     ENDTRY
  557. }
  558.  
  559. //------------------------------------------------------------------------------
  560. // Method:        CheckForDrag
  561. //
  562. // Description:    This method is called to test for the user's dragging of the
  563. //                selection.
  564. //------------------------------------------------------------------------------
  565.  
  566. ODBoolean CSelection::CheckForDrag(Environment* ev, ODEventData* event)
  567. {
  568.     ASSERT(fInited != kODFalse, kAssertionFailed);
  569.  
  570.     ODBoolean yes = WaitMouseMoved(event->where);
  571.     return yes;
  572. }
  573.  
  574. //------------------------------------------------------------------------------
  575. // Method:        Drag
  576. //
  577. // Description:    This method is called to initiate a drag operation for the
  578. //                current selection.
  579. //------------------------------------------------------------------------------
  580.  
  581. void CSelection::Drag(Environment* ev, ODFacet* facet, ODEventData* event,
  582.                         ODEventInfo* eventInfo)
  583. {
  584.     ASSERT(fInited != kODFalse, kAssertionFailed);
  585.  
  586.     ODDropResult    result = kODDropFail;
  587.     ODPart*            part = kODNULL;
  588.     ODFrame*        frame = facet->GetFrame(ev);
  589.     ODSLong            error = noErr;
  590.     
  591.     ODVolatile(part);
  592.     ODVolatile(error);
  593.  
  594.     ODDragAndDrop* dragdrop = fSession->GetDragAndDrop(ev);
  595.     
  596.     // Remove existing data from the drag container.
  597.     dragdrop->Clear(ev);
  598.     
  599.     // Add our content property to the drag container.
  600.     ODStorageUnit* dragdropSU = dragdrop->GetContentStorageUnit(ev);
  601.     dragdropSU->AddProperty(ev, kODPropContents);
  602.     dragdropSU->AddValue(ev, kPanelEditorKind);
  603.     
  604.     // Externalize the current selection.
  605.     this->Write(ev, dragdropSU);
  606.     
  607.     // Calculate the drag feedback offset in global coordinates.
  608.     Point pt = {0,0};
  609.     {
  610.         CFocus initiateDrawing(ev, eventInfo->embeddedFacet);
  611.         LocalToGlobal(&pt);
  612.     }
  613.     
  614.     // Get the embedded frame shape as a region for dragging feedback.
  615.     ODFrame* embFrame = eventInfo->embeddedFacet->GetFrame(ev);
  616.     
  617.     RgnHandle selectionRgn = kODNULL;
  618.     {
  619.         CListIterator fiter(fItems);
  620.         CListItem* item = (CListItem*)fiter.First();
  621.         selectionRgn = item->GetSelectedRegion(ev);
  622.     }
  623.     
  624.     OffsetRgn((RgnHandle)selectionRgn, pt.h, pt.v);
  625.     
  626.     // Let the rest of OpenDoc know we are dragging the embedded frame.
  627.     embFrame->SetDragging(ev, kODTrue);
  628.         
  629.     RgnHandle dragRgn = NewRgn();
  630.     CopyRgn((RgnHandle) selectionRgn, dragRgn);
  631.     InsetRgn(dragRgn, -1, -1);
  632.     DiffRgn(dragRgn, (RgnHandle) selectionRgn, dragRgn);
  633.     
  634.     // Start Undo recording.
  635.     this->PushUndoState(ev, kUndoDrag, kODBeginAction);
  636.     
  637.     // Capture the "current" selection so we can operate on it if necessary.
  638.     CList* currentSelection = this->CaptureItems();
  639.  
  640.     // Create Byte Arrays for the 2 dynamic parameters
  641.     ODByteArray dragRgnBA = CreateByteArrayStruct(&dragRgn, sizeof(RgnHandle));
  642.     ODByteArray eventBA = CreateByteArrayStruct(&event, sizeof(ODEventData*));
  643.  
  644.     ODVolatile(dragRgnBA);
  645.     ODVolatile(eventBA);
  646.  
  647.     TRY
  648.         result = dragdrop->StartDrag(ev, frame, kODDragImageRegionHandle, &dragRgnBA, &part, &eventBA);
  649.         
  650.         // Dispose byte arrays
  651.         DisposeByteArrayStruct(dragRgnBA);
  652.         DisposeByteArrayStruct(eventBA);
  653.         
  654.         // Handle drop result.
  655.         if ( result == kODDropMove )
  656.         {
  657.             // Get a valid item to add to the selection.
  658.             CListItem* nearItem = fOwner->GetItemNearSelection();
  659.         
  660.             CListIterator fiter(currentSelection);
  661.             for ( CListItem* item = (CListItem*)fiter.First();
  662.                     fiter.IsNotComplete();
  663.                     item = (CListItem*)fiter.Next() )
  664.             {
  665.                 // Ask the owner to remove the item from internal collections.
  666.                 fOwner->RemoveListItem(ev, item);
  667.                 // Remove the item from the selection.
  668.                 this->Remove(ev, item);
  669.                 // Detach the item from the document frame hierarchy.
  670.                 item->Detach(ev);
  671.                 // Remove and release the item.
  672.                 fiter.RemoveCurrent();
  673.                 item->Release(ev);
  674.             }
  675.  
  676.             // Update the selection.
  677.             fOwner->UpdateSelection(ev, nearItem);
  678.             // Dirty the draft.
  679.             fOwner->SetDirty(ev);
  680.         }
  681.         
  682.     CATCH_ALL
  683.         // Dispose byte arrays
  684.         DisposeByteArrayStruct(dragRgnBA);
  685.         DisposeByteArrayStruct(eventBA);
  686.         
  687.         // Save the error so we can return it.
  688.         error = ErrorCode();
  689.     ENDTRY
  690.     
  691.     delete currentSelection;
  692.     
  693.     // Start Undo recording.
  694.     this->PushUndoState(ev, kUndoDrag, kODEndAction);
  695.     
  696.     // Let the rest of OpenDoc know we are dragging the embedded frame.
  697.     embFrame->SetDragging(ev, kODFalse);
  698.     
  699.     // Dispose drag selection feedback region.
  700.     DisposeRgn(dragRgn);
  701.     
  702.     // The destination part must be released.
  703.     ODSafeReleaseObject(part);
  704.     
  705.     // If there was an error during dragging, make sure to report it.
  706.     THROW_IF_ERROR(error);
  707. }
  708.  
  709. //------------------------------------------------------------------------------
  710. // Method:        GetFirstItem
  711. //
  712. // Description:    
  713. //------------------------------------------------------------------------------
  714.  
  715. CListItem* CSelection::GetFirstItem()
  716. {
  717.     ASSERT(fInited != kODFalse, kAssertionFailed);
  718.  
  719.     CListIterator iter(fItems);
  720.     return (CListItem*) iter.First();
  721. }
  722.  
  723. //------------------------------------------------------------------------------
  724. // Method:        GetLastItem
  725. //
  726. // Description:    
  727. //------------------------------------------------------------------------------
  728.  
  729. CListItem* CSelection::GetLastItem()
  730. {
  731.     ASSERT(fInited != kODFalse, kAssertionFailed);
  732.  
  733.     CListIterator iter(fItems);
  734.     return (CListItem*) iter.Last();
  735. }
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.